package com.beiding.hotcode;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public abstract class MyInstance {

    InstanceLifecycle instanceLifecycle = InstanceLifecycle.EMPTY;

    public void setInstanceLifecycle(InstanceLifecycle instanceLifecycle) {
        if (instanceLifecycle == null) {
            this.instanceLifecycle = InstanceLifecycle.EMPTY;
        } else {
            this.instanceLifecycle = instanceLifecycle;
        }
    }

    Map<String, Map<Integer, List<MethodHolder>>> methods = new HashMap<>();

    public abstract Class getType();

    public abstract MyClass getMyClass();

    public abstract Object getInstance();

    public abstract Object invokeCatch(String method, Object... params) throws Throwable;

    public abstract void set(String field, Object value);

    public abstract void forceSet(String field, Object value);

    public abstract Object get(String field);

    public <T> T get(String field, Class<T> type) {
        return (T) get(field);
    }

    public abstract Object forceGet(String field);

    public <T> T forceGet(String field, Class<T> type) {
        return (T) forceGet(field);
    }


    public Object invoke(String method, Object... params) {
        try {
            return invokeCatch(method, params);
        } catch (Throwable e) {
            if (e instanceof RuntimeException) {
                throw (RuntimeException) e;
            }
            RuntimeException runtimeException = new RuntimeException(e.getMessage(), e.getCause());
            runtimeException.setStackTrace(e.getStackTrace());
            throw runtimeException;
        }
    }

    public abstract <T> MyMethod<T> method(String name, Class<T> type);

    public MyMethod method(String name) {
        return method(name, Object.class);
    }

}
